// 版权所有2010 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package json

// JSON值解析器状态机。
// 几乎达到了手写的合理限度。
// 有些部分有点乏味，但总的来说，它很好地排除了
// 或者这个包中多个扫描函数
// 中的常见代码（紧凑、缩进、检查有效等）。
// 
// 在深入到扫描仪本身之前，本文件以使用扫描仪的两个简单示例开始。

import (
	"strconv"
	"sync"
)

// Valid报告数据是否为有效的JSON编码。
func Valid(data []byte) bool {
	scan := newScanner()
	defer freeScanner(scan)
	return checkValid(data, scan) == nil
}

// checkValid验证数据是否为有效的JSON编码数据。
// 将扫描传递给checkValid使用，以避免分配。
func checkValid(data []byte, scan *scanner) error {
	scan.reset()
	for _, c := range data {
		scan.bytes++
		if scan.step(scan, c) == scanError {
			return scan.err
		}
	}
	if scan.eof() == scanError {
		return scan.err
	}
	return nil
}

// 语法错误是对JSON语法错误的描述。
type SyntaxError struct {
	msg    string // 错误说明
	Offset int64  // 读取偏移字节后发生错误
}

func (e *SyntaxError) Error() string { return e.msg }

// 扫描仪是JSON扫描状态机。
// 呼叫者呼叫扫描。重置，然后通过调用scan一次一个字节地传递
// 字节。每个字节的步骤（&扫描，c）。
// 返回值被称为操作码，它告诉
// 调用者一些重要的解析事件，比如开始
// 和结束文字、对象和数组，以便
// 调用者可以根据自己的意愿跟随。
// 返回值scanned表示一个顶级
// JSON值已完成，*在刚刚传入的字节之前。（指示必须延迟，以便
// 识别数字的结尾：123是整数值还是
// 12345e+6的开头？）。
type scanner struct {
	// 该步骤是一个函数，将被调用以执行下一个转换。
	// 也尝试过使用一个整型常量和一个带开关的单func 
	// 但在64位Mac Mini上直接使用func比
	// 快10%，阅读起来更好。
	step func(*scanner, byte) int

	// 已达到顶级值的末尾。ABCDEG
	endTop bool

	parseState []int

	// 发生的错误，如果有的话。
	err error

	// 消耗的总字节数，由解码器更新。解码（并故意
	// 未通过扫描重置设置为零）
	bytes int64
}

var scannerPool = sync.Pool{
	New: func() any {
		return &scanner{}
	},
}

func newScanner() *scanner {
	scan := scannerPool.Get().(*scanner)
	// 扫描。reset by design不会将字节设置为零
	scan.bytes = 0
	scan.reset()
	return scan
}

func freeScanner(scan *scanner) {
	// 避免在极端情况下占用太多内存。
	if len(scan.parseState) > 1024 {
		scan.parseState = nil
	}
	scannerPool.Put(scan)
}

// 这些值由分配给扫描仪的状态转换函数
// 返回。状态和方法扫描程序。eof。
// 他们提供了有关当前扫描状态的详细信息，呼叫方可能有兴趣了解这些信息。
// 可以忽略任何特定
// 调用scanner的返回值。状态：如果一个调用返回scanError，
// 随后的每个调用也将返回scanError。
const (
	// 继续。
	scanContinue     = iota // 无趣字节
	scanBeginLiteral        // 下一个结果隐含的结束！=scanContinue 
	scanBeginObject         // 开始对象
	scanObjectKey           // 刚刚完成的对象键（字符串）
	scanObjectValue         // 刚刚完成的非最后一个对象值
	scanEndObject           // 结束对象（如果可能的话暗示扫描对象值）
	scanBeginArray          // 开始数组
	scanArrayValue          // 刚刚完成的数组值
	scanEndArray            // 结束数组（如果可能暗示扫描数组值）
	scanSkipSpace           // 空格字节；可以跳过；已知是最后一个“继续”结果

	// 停止。
	scanEnd   // 顶级值结束*在*这个字节之前；已知的第一个“停止”结果
	scanError // 遇到错误，扫描仪。犯错误
)

// 这些值存储在parseState堆栈中。
// 它们给出了正在扫描的复合值
// 的当前状态。如果解析器位于嵌套值
// 内，则parseState描述嵌套状态，最外层为条目0。
const (
	parseObjectKey   = iota // 解析对象键（冒号前）
	parseObjectValue        // 解析对象值（冒号后）
	parseArrayValue         // 解析数组值
)

// 这限制了最大嵌套深度以防止堆栈溢出。
// 这是法律允许的https:
const maxNestingDepth = 10000

// 重置使扫描仪准备好使用。
// 必须在调用s.step之前调用它。
func (s *scanner) reset() {
	s.step = stateBeginValue
	s.parseState = s.parseState[0:0]
	s.err = nil
	s.endTop = false
}

// eof告诉扫描器输入已经结束。
// 它会像s.step一样返回扫描状态。
func (s *scanner) eof() int {
	if s.err != nil {
		return scanError
	}
	if s.endTop {
		return scanEnd
	}
	s.step(s, ' ')
	if s.endTop {
		return scanEnd
	}
	if s.err == nil {
		s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
	}
	return scanError
}

// pushParseState将新的解析状态p推送到解析堆栈上。
// 如果超过maxNestingDepth，则返回错误状态，否则返回successState。
func (s *scanner) pushParseState(c byte, newParseState int, successState int) int {
	s.parseState = append(s.parseState, newParseState)
	if len(s.parseState) <= maxNestingDepth {
		return successState
	}
	return s.error(c, "exceeded max depth")
}

// popParseState从堆栈中弹出一个解析状态（已获得），并相应地更新s.step。
func (s *scanner) popParseState() {
	n := len(s.parseState) - 1
	s.parseState = s.parseState[0:n]
	if n == 0 {
		s.step = stateEndTop
		s.endTop = true
	} else {
		s.step = stateEndValue
	}
}

func isSpace(c byte) bool {
	return c <= ' ' && (c == ' ' || c == '\t' || c == '\r' || c == '\n')
}

// stateBeginValueOrEmpty是阅读后的状态`[`.
func stateBeginValueOrEmpty(s *scanner, c byte) int {
	if isSpace(c) {
		return scanSkipSpace
	}
	if c == ']' {
		return stateEndValue(s, c)
	}
	return stateBeginValue(s, c)
}

// stateBeginValue是输入开头的状态。
func stateBeginValue(s *scanner, c byte) int {
	if isSpace(c) {
		return scanSkipSpace
	}
	switch c {
	case '{':
		s.step = stateBeginStringOrEmpty
		return s.pushParseState(c, parseObjectKey, scanBeginObject)
	case '[':
		s.step = stateBeginValueOrEmpty
		return s.pushParseState(c, parseArrayValue, scanBeginArray)
	case '"':
		s.step = stateInString
		return scanBeginLiteral
	case '-':
		s.step = stateNeg
		return scanBeginLiteral
	case '0': // 0.123的开头
		s.step = state0
		return scanBeginLiteral
	case 't': // true的开头
		s.step = stateT
		return scanBeginLiteral
	case 'f': // false的开头
		s.step = stateF
		return scanBeginLiteral
	case 'n': // null的开头
		s.step = stateN
		return scanBeginLiteral
	}
	if '1' <= c && c <= '9' { // 1234.5的开头
		s.step = state1
		return scanBeginLiteral
	}
	return s.error(c, "looking for beginning of value")
}

// stateBeginStringOrEmpty是读取后的状态`{`.
func stateBeginStringOrEmpty(s *scanner, c byte) int {
	if isSpace(c) {
		return scanSkipSpace
	}
	if c == '}' {
		n := len(s.parseState)
		s.parseState[n-1] = parseObjectValue
		return stateEndValue(s, c)
	}
	return stateBeginString(s, c)
}

// statebeaginstring是读取`{“key”：value`后的状态。
func stateBeginString(s *scanner, c byte) int {
	if isSpace(c) {
		return scanSkipSpace
	}
	if c == '"' {
		s.step = stateInString
		return scanBeginLiteral
	}
	return s.error(c, "looking for beginning of object key string")
}

// stateEndValue是完成一个值后的状态，
// 例如，在读取`{}`或` true`或`[“x”后的状态`.
func stateEndValue(s *scanner, c byte) int {
	n := len(s.parseState)
	if n == 0 {
		// 在当前字节之前完成顶层。
		s.step = stateEndTop
		s.endTop = true
		return stateEndTop(s, c)
	}
	if isSpace(c) {
		s.step = stateEndValue
		return scanSkipSpace
	}
	ps := s.parseState[n-1]
	switch ps {
	case parseObjectKey:
		if c == ':' {
			s.parseState[n-1] = parseObjectValue
			s.step = stateBeginValue
			return scanObjectKey
		}
		return s.error(c, "after object key")
	case parseObjectValue:
		if c == ',' {
			s.parseState[n-1] = parseObjectKey
			s.step = stateBeginString
			return scanObjectValue
		}
		if c == '}' {
			s.popParseState()
			return scanEndObject
		}
		return s.error(c, "after object key:value pair")
	case parseArrayValue:
		if c == ',' {
			s.step = stateBeginValue
			return scanArrayValue
		}
		if c == ']' {
			s.popParseState()
			return scanEndArray
		}
		return s.error(c, "after array element")
	}
	return s.error(c, "")
}

// stateEndTop是完成顶级值后的状态，
// 例如在读取“{}”或“[1,2,3]”后的状态。
// 现在只能看到空格字符。
func stateEndTop(s *scanner, c byte) int {
	if !isSpace(c) {
		// 在下一次通话中抱怨无空格字节。
		s.error(c, "after top-level value")
	}
	return scanEnd
}

// stateInString是读取“%”后的状态。
func stateInString(s *scanner, c byte) int {
	if c == '"' {
		s.step = stateEndValue
		return scanContinue
	}
	if c == '\\' {
		s.step = stateInStringEsc
		return scanContinue
	}
	if c < 0x20 {
		return s.error(c, "in string literal")
	}
	return scanContinue
}

// stateInStringEsc是在带引号的字符串中读取“%”后的状态。
func stateInStringEsc(s *scanner, c byte) int {
	switch c {
	case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
		s.step = stateInString
		return scanContinue
	case 'u':
		s.step = stateInStringEscU
		return scanContinue
	}
	return s.error(c, "in string escape code")
}

// stateInStringEscU是在引用字符串中读取““\u”后的状态。
func stateInStringEscU(s *scanner, c byte) int {
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
		s.step = stateInStringEscU1
		return scanContinue
	}
	// numbers 
	return s.error(c, "in \\u hexadecimal character escape")
}

// stateInStringEscU1是在引用字符串中读取“\u1”后的状态。
func stateInStringEscU1(s *scanner, c byte) int {
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
		s.step = stateInStringEscU12
		return scanContinue
	}
	// numbers 
	return s.error(c, "in \\u hexadecimal character escape")
}

// stateInStringEscU12是在引用字符串中读取““\u12”后的状态。
func stateInStringEscU12(s *scanner, c byte) int {
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
		s.step = stateInStringEscU123
		return scanContinue
	}
	// numbers 
	return s.error(c, "in \\u hexadecimal character escape")
}

// stateInStringEscU123是在引用字符串中读取“\u123”后的状态。
func stateInStringEscU123(s *scanner, c byte) int {
	if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
		s.step = stateInString
		return scanContinue
	}
	// numbers 
	return s.error(c, "in \\u hexadecimal character escape")
}

// stateNeg是在一个数字中读取“-”后的状态。
func stateNeg(s *scanner, c byte) int {
	if c == '0' {
		s.step = state0
		return scanContinue
	}
	if '1' <= c && c <= '9' {
		s.step = state1
		return scanContinue
	}
	return s.error(c, "in numeric literal")
}

// state1是在数字期间读取非零整数后的状态，
// 例如在读取'1'或'100'但不是'0'后的状态。
func state1(s *scanner, c byte) int {
	if '0' <= c && c <= '9' {
		s.step = state1
		return scanContinue
	}
	return state0(s, c)
}

// state0是在一个数字中读取'0'后的状态。
func state0(s *scanner, c byte) int {
	if c == '.' {
		s.step = stateDot
		return scanContinue
	}
	if c == 'e' || c == 'E' {
		s.step = stateE
		return scanContinue
	}
	return stateEndValue(s, c)
}

// stateDot是读取数字中的整数和小数点后的状态，
// 例如读取'1'后的状态。
func stateDot(s *scanner, c byte) int {
	if '0' <= c && c <= '9' {
		s.step = stateDot0
		return scanContinue
	}
	return s.error(c, "after decimal point in numeric literal")
}

// stateDot0是读取整数、小数点和后续
// 数字后的状态，例如读取'3.14'后的状态。
func stateDot0(s *scanner, c byte) int {
	if '0' <= c && c <= '9' {
		return scanContinue
	}
	if c == 'e' || c == 'E' {
		s.step = stateE
		return scanContinue
	}
	return stateEndValue(s, c)
}

// stateE是在读取一个数字的尾数和e之后的状态，
// 例如在读取'314e'或'0.314e'之后的状态。
func stateE(s *scanner, c byte) int {
	if c == '+' || c == '-' {
		s.step = stateESign
		return scanContinue
	}
	return stateESign(s, c)
}

// statesign是在读取尾数e并在数字上签名后的状态，例如在读取'314e-'或'0.314e+'后的状态。
func stateESign(s *scanner, c byte) int {
	if '0' <= c && c <= '9' {
		s.step = stateE0
		return scanContinue
	}
	return s.error(c, "in exponent of numeric literal")
}

// state0是在读取尾数e、可选符号
// 和数字中至少一位指数后的状态，例如在读取'314e-2'或'0.314e+1'或'3.14e0'后的状态。
func stateE0(s *scanner, c byte) int {
	if '0' <= c && c <= '9' {
		return scanContinue
	}
	return stateEndValue(s, c)
}

// stateT是读取't'后的状态。
func stateT(s *scanner, c byte) int {
	if c == 'r' {
		s.step = stateTr
		return scanContinue
	}
	return s.error(c, "in literal true (expecting 'r')")
}

// stateTr是读取'tr'后的状态。
func stateTr(s *scanner, c byte) int {
	if c == 'u' {
		s.step = stateTru
		return scanContinue
	}
	return s.error(c, "in literal true (expecting 'u')")
}

// stateTru是读取'tru'后的状态。
func stateTru(s *scanner, c byte) int {
	if c == 'e' {
		s.step = stateEndValue
		return scanContinue
	}
	return s.error(c, "in literal true (expecting 'e')")
}

// stateF是读取'f'后的状态。
func stateF(s *scanner, c byte) int {
	if c == 'a' {
		s.step = stateFa
		return scanContinue
	}
	return s.error(c, "in literal false (expecting 'a')")
}

// stateFa是读取'fa'后的状态。
func stateFa(s *scanner, c byte) int {
	if c == 'l' {
		s.step = stateFal
		return scanContinue
	}
	return s.error(c, "in literal false (expecting 'l')")
}

// stateFal是读了'fal'之后的状态。
func stateFal(s *scanner, c byte) int {
	if c == 's' {
		s.step = stateFals
		return scanContinue
	}
	return s.error(c, "in literal false (expecting 's')")
}

// stateFals是读了'fals'之后的状态。
func stateFals(s *scanner, c byte) int {
	if c == 'e' {
		s.step = stateEndValue
		return scanContinue
	}
	return s.error(c, "in literal false (expecting 'e')")
}

// stateN是读取'n'后的状态。
func stateN(s *scanner, c byte) int {
	if c == 'u' {
		s.step = stateNu
		return scanContinue
	}
	return s.error(c, "in literal null (expecting 'u')")
}

// stateNu是读取'nu'后的状态。
func stateNu(s *scanner, c byte) int {
	if c == 'l' {
		s.step = stateNul
		return scanContinue
	}
	return s.error(c, "in literal null (expecting 'l')")
}

// stateNul是读取'nul'后的状态。
func stateNul(s *scanner, c byte) int {
	if c == 'l' {
		s.step = stateEndValue
		return scanContinue
	}
	return s.error(c, "in literal null (expecting 'l')")
}

// stateError是到达语法错误后的状态，
// 例如在读了“[1}”或“5.1.2”之后。
func stateError(s *scanner, c byte) int {
	return scanError
}

// 错误记录一个错误并切换到错误状态。
func (s *scanner) error(c byte, context string) int {
	s.step = stateError
	s.err = &SyntaxError{"invalid character " + quoteChar(c) + " " + context, s.bytes}
	return scanError
}

// quoteChar格式c作为引用字符文字
func quoteChar(c byte) string {
	// 特殊情况-不同于引用字符串
	if c == '\'' {
		return `'\''`
	}
	if c == '"' {
		return `'"'`
	}

	// 使用带不同引号的引用字符串
	s := strconv.Quote(string(c))
	return "'" + s[1:len(s)-1] + "'"
}
